package com.match.match;

import java.math.BigDecimal;
import java.util.List;
import com.hazelcast.core.HazelcastInstance;
import com.hazelcast.map.IMap;
import com.match.common.model.dto.LevelMatch;
import com.match.common.model.dto.MatchOrder;
import com.match.common.model.dto.Trade;
import com.match.constant.DealWay;
import com.match.constant.OrderState;
import com.match.plugin.hazelcast.HazelcastKit;
import com.match.plugin.kafka.Kafka;

/**
 * @ClassName: LimitOrderMatchService
 * @Description: TODO(市价撮合服务)不指定价格按照当前最好的价格
 */
public class MarketOrderMatchService {
	
	private static MarketOrderMatchService marketOrderMatchService = new MarketOrderMatchService();
	
	public static MarketOrderMatchService getMarketOrderMatchService(){
        return marketOrderMatchService;
    }
	
	public MatchOrder doMatch(MatchOrder input,HazelcastInstance hzInstance,MatchDetailHandler matchDetailHandler) {
		try {
			// 获取对手盘口
			IMap<BigDecimal, BigDecimal> outMap = hzInstance.getMap(HazelcastKit.getMatchKey(input.getCoinTeam(), !input.getIsBuy()));
			if (null!=outMap&&outMap.size()>0) {
				BigDecimal outPrice = HazelcastKit.getOptimalMatch(outMap,input.getIsBuy()); 
				if (HazelcastKit.canMatch(input, outPrice)) {
					BigDecimal outNum = outMap.get(outPrice);
					if (outNum.compareTo(BigDecimal.ZERO)<1) {
						outMap.remove(outPrice);
						doMatch(input,hzInstance,matchDetailHandler); // 递归处理
					}
					int contrast = input.getUnFinishNumber().compareTo(outNum);
					BigDecimal dealNum = contrast > -1?outNum:input.getUnFinishNumber();
					input.setFinishNumber(input.getFinishNumber().add(dealNum));
					input.setUnFinishNumber(input.getUnFinishNumber().subtract(dealNum));
					if (input.getIsBuy()) {
						input.setSurplusFrozen(input.getSurplusFrozen().subtract(outPrice.multiply(dealNum)));
					}else {
						input.setSurplusFrozen(input.getSurplusFrozen().subtract(dealNum));
					}
					//撮合详情记录 >>> 一个价格一个详情（数据库记录这个订单的变化过程，每次交易了多少，记录）（可以不用发给用户）
					Kafka.send(Kafka.matchTrade, Kafka.matchTrade, input.getId(),
							new Trade().setUid(input.getUid())
							.setOid(input.getId())
							.setIsBuy(input.getIsBuy())
							.setNumber(dealNum)
							.setPrice(outPrice)
							.setTotalPrice(dealNum.multiply(outPrice))
							.setCoinTeam(input.getCoinTeam())
							.setDealWay(DealWay.TAKER.value)
					);
					
					List<LevelMatch> lms = input.getList();
					LevelMatch lm = new LevelMatch(outPrice, dealNum);
					lm.setEatUp(contrast > -1 ?true:false);
					lms.add(lm);
					input.setList(lms);
					if (contrast == 1) {//水平价格被吃完
						outMap.remove(outPrice);
						input.setState(OrderState.SOME_DEAL.value);
						doMatch(input,hzInstance,matchDetailHandler); // 递归处理
					}else if (contrast == 0) {//都被吃完
						outMap.remove(outPrice);
						input.setState(OrderState.FINISH_DEAL.value);
					}else {//水平价格有剩余
						outMap.compute(outPrice, (k,v) -> v.subtract(dealNum));
						input.setState(OrderState.FINISH_DEAL.value);
					}
				}
			}
		} catch (Exception e) {
			System.out.println("执行撮合错误："+e);
			System.out.println("执行撮合错误源数据："+input);
			input.setState(3);//撤销掉
		} 
		if (input.getState().intValue()!=OrderState.FINISH_DEAL.value) {
			//市价没吃完，直接撤销
			input.setState(OrderState.CANCEL.value);
		}
		
		try {
			//当状态大于1时，不造成深度变化
			if (input.getState().intValue()==0||input.getState().intValue()==1) {
				IMap<BigDecimal, BigDecimal> map = hzInstance.getMap(HazelcastKit.getMatchKey(input.getCoinTeam(), input.getIsBuy()));
				IMap<Long, MatchOrder> order_map = hzInstance.getMap(HazelcastKit.getOrderBookKey(input.getCoinTeam(), input.getIsBuy()));
				map.compute(input.getPrice(),(k, v) -> HazelcastKit.numberAdd(v, input.getUnFinishNumber()));
				order_map.put(input.getId(), input);
			}
			if (input.getState().intValue()!=0) {
				Kafka.send(Kafka.orderChange,Kafka.orderChange,input.getId(),input);
			}
		} catch (Exception e) {
			e.printStackTrace();
			System.out.println("===入单消费错误："+e);
		}
		
		
		return input;
	}

}
